_package("alz.mui");

_import("alz.core.EventTarget");

/**
 * 基础组件类，所有组件类都应该是该类的子类
 */
_class("Component", EventTarget, function(){
	this._init = function(){
		_super._init.call(this);
		this._disabled = false;  //是否禁用
		this._data = null;  //原始的json数据
		this._self = null;  //DOM元素
		this._tag = "div";  //标签名
		this._id = "";  //ID标识
		this._visible = true;  //是否可见
		this._zIndex = 0;  //
		this._opacity = 0;  //透明度
		this._animation = runtime._animation;
		/*
		this._enables = {  //组件启用的特性列表
			"action": false
		};
		*/
		//组件的扩展模块
		//_action
		//_layout
		//_align
		//_effect
		//_tag
	};
	this.create = function(parent){
		runtime.error("[ERROR]组件" + this._className + "需要实现create方法");
	};
	this.bind = function(obj){
		runtime.error("[ERROR]组件" + this._className + "需要实现bind方法");
	};
	this.init = function(obj){
		if(!obj && !("tagName" in obj)){
			runtime.error("[Component::init]参数obj不能为空，请检查组件的创建过程");
		}
		obj._ptr = this;
		this._self = obj;
		this._tag = obj.tagName.toLowerCase();
	};
	this.dispose = function(){
		this._animation = null;
		if(this._self){
			this._self._ptr = null;
			this._self = null;
		}
		this._data = null;
		_super.dispose.apply(this);
	};
	this.query = function(xpath/*, context*/){
		/*
		context = context || this._self;
		if(context == null){
			runtime.error("[Component::query]context is null!");
		}
		return runtime._xpq.query(xpath, context);
		*/
		return this._self.querySelectorAll(xpath);
	};
	this.find = function(xpath/*, context*/){
		//return this.query(xpath, context)[0];
		return this._self.querySelector(xpath);
	};
	this._createTextNode = function(text){
		return document.createTextNode(text);
	};
	this._createElement = function(tag){
		return document.createElement(tag);
	};
	this._renderElement = function(parent, obj){
		if(parent.getContainer){
			parent = parent.getContainer();
		}
		if(this.__insert){
			parent.insertBefore(obj, this.__insert);
		}else{
			parent.appendChild(obj);
		}
	};
	this.createElement = function(parent, tag, cls){
		var obj = document.createElement(tag);
		if(cls){
			obj.className = cls;
		}
		if(parent){
			this._renderElement(parent, obj);
		}
		return obj;
	};
	this.createDomElement = function(parent, html, exp){
		var obj = runtime.createDomElement(html, exp);
		if(parent){
			this._renderElement(parent, obj);
		}
		return obj;
	};
	this.appendHtml = function(parent, html){
		var div = document.createElement("div");
		div.innerHTML = html;
		var nodes = div.childNodes;
		while(nodes.length > 0){
			parent.appendChild(nodes[0]);
		}
	};
	this.setStyleProperty = function(name, value){
		try{
			if(this._self){
				this._self.style[name] = value;
			}
		}catch(ex){
			runtime.error(ex.message + "\n" + name + "=" + value);
		}
	};
	this.getData = function(){
		return this._data;
	};
	this.setData = function(v){
		this._data = v;
	};
	this.getElement = function(){
		return this._self;
	};
	this.getContainer = function(){
		return this._self;
	};
	this.getId = function(){
		return this._id;
	};
	this.setId = function(v){
		this._id = v;
	};
	this.getDisabled = function(){
		return this._disabled;
	};
	this.setDisabled = function(v){
		this._disabled = v;
		if(this._self){
			this._self.disabled = v;
		}
	};
	this.getVisible = function(){
		return this._visible;
	};
	this.setVisible = function(v){
		if(this._visible == v) return;
		if(this._self){
			this._self.style.display = v ? "" : "none";
		}
		this._visible = v;
	};
	this.getZIndex = function(){
		return this._zIndex;
	};
	this.setZIndex = function(v){
		this._zIndex = v;
		this.setStyleProperty("zIndex", v);
	};
	this.getOpacity = function(){
		return this._opacity;
	};
	this.setOpacity = function(v){
		v = Math.max(0, Math.min(1, v));
		if(this._opacity == v) return;
		if(runtime.ie){
			v = Math.round(v * 100);
			this.setStyleProperty("filter", v == 100 ? "" : "Alpha(Opacity=" + v + ")");
		}else if(runtime.moz){
			this.setStyleProperty("MozOpacity", v == 1 ? "" : v);
		}else if(runtime.opera || runtime.safari || runtime.chrome){
			this.setStyleProperty("opacity", v == 1 ? "" : v);
		}
		this._opacity = v;
	};
	this.setTop = function(v){
		if(this._self){
			this._self.style.top = Math.round(v) + "px";
		}
	};
	this.setHeight = function(v){
		if(this._self){
			this._self.style.height = Math.max(0, Math.round(v)) + "px";
		}
	};
	this.getViewPort = function(){
		return {
			"x": this._self.scrollLeft,
			"y": this._self.scrollTop,
			"w": this._self.clientWidth,  //Math.max(this._self.clientWidth || this._self.scrollWidth)
			"h": Math.max(this._self.clientHeight, this._self.parentNode.clientHeight)  //Math.max(this._self.clientHeight || this._self.scrollHeight)
		};
	};
	this.moveToCenter = function(){
		var parent = this._self.parentNode;  //window.document.documentElement
		var cw = parent.clientWidth;
		var ch = parent.clientHeight;
		this.moveTo(
			Math.ceil((cw - this._self.offsetWidth ) / 2),
			Math.ceil((ch - this._self.offsetHeight) / 2)
		);
	};
	this.moveTo = function(x, y){
		if(this._self){
			this._self.style.left = x + "px";
			this._self.style.top = y + "px";
		}
	};
	this.resize = function(w, h){
		if(this._self){
			this._self.style.width  = Math.max(0, w) + "px";
			this._self.style.height = Math.max(0, h) + "px";
		}
	};
	//动画效果相关接口
	this.animate = function(el, style, speed, easingfun, agent, func){
		this._animation.animate(el, style, speed, easingfun, agent, func);
	};
	this.show = function(el, speed, agent, func){
		this._animation.show(el, speed, agent, func);
	};
	this.hide = function(el, speed, agent, func){
		this._animation.hide(el, speed, agent, func);
	};
	this.toggle = function(el, speed, agent, func){
		this._animation.toggle(el, speed, agent, func);
	};
	this.fadeIn = function(el, speed, agent, func){
		this._animation.fadeIn(el, speed, agent, func);
	};
	this.fadeOut = function(el, speed, agent, func){
		this._animation.fadeOut(el, speed, agent, func);
	};
	this.slideDown = function(el, speed, agent, func){
		this._animation.slideDown(el, speed, agent, func);
	};
	this.slideUp = function(el, speed, agent, func){
		this._animation.slideUp(el, speed, agent, func);
	};
	//事件绑定接口
	this.addListener = function(el, type, agent, func){
		runtime._eventManager.addListener(el, type, agent, func);
	};
	this.removeListener = function(el, type){
		runtime._eventManager.removeListener(el, type);
	};
	/**
	 * 通过判断是否绑定有 js 组件对象来确定UI组件
	 */
	this.getControl = function(el){
		while(!el._ptr){
			el = el.parentNode;
			if(!el || el.tagName == "BODY" || el.tagName == "HTML"){
				return null;
			}
		}
		return el._ptr;
	};
	this._cssKeyToJsKey = function(str){
		return str.replace(/-([a-z])/g, function(_0, _1){
			return _1.toUpperCase();
		});
	};
	this.applyCssStyle = function(el, css, className){
		var style = css[(el.className == "error" ? "error-" : "") + className];
		for(var k in style){
			if(k.charAt(0) == "_"){
				var obj = el.getElementsByTagName(k.substr(1))[0];
				for(var key in style[k]){
					var name = this._cssKeyToJsKey(key);
					if(obj.style[name] != style[k][key]){
						obj.style[name] = style[k][key];
					}
				}
				obj = null;
			}else{
				var name = this._cssKeyToJsKey(k);
				if(el.style[name] != style[k]){
					el.style[name] = style[k];
				}
			}
		}
	};
});